/*
 * @Author: your name
 * @Description: 
 * @FilePath: /log/logger.h
 */

class Logger
{
public:
    enum LogLevel
    {
        TRACE = 1,
        DEBUG,
        INFO,
        WARN,
        ERROR,
        FATAL,
    };

    Logger();
    ~Logger();

    LogStream& stream() {}

    static LogLevel LogLevel() {return level_;}
    static void SetLogLeveL(LogLevel level) {level_ = level;}

    using OutputFunc = std::function<void(const char* msg, int len);
    using FlushFunc = std::function<void()>;
    static void SetOutput(OutputFunc);//将buffer中内容从缓冲区 写到 文件（还是在内存上）
    static void SetFlush(FlushFunc);//冲刷到磁盘
private:

//内部类，隐藏实现；
//功能：格式化日志消息
class Impl
{
public:
    Impl();
    void FormatTime();
private:
    TimeStamp time_;
    LogStream stream_;
    LogLevel level_;
    int line_;
    SourceFile basename_;
}；
    Impl impl_;

}
#define LOG_TRACE if(Logger::LogLevel() <= Logger::TRACE)
    Logger(__FILE__, __LINE__, Logger::TRACE, __func__).stream()
#define LOG_DEBUG if(Logger::LogLevel() <= Logger::DEBUG)
    Logger(__FILE__, __LINE__, Logger::DEBUG, __func__).stream()
#define LOG_INFO if(Logger::LogLevel() <= Logger::INFO)
    Logger(__FILE__, __LINE__, Logger::INFO, __func__).stream()
#define LOG_WARN if(Logger::LogLevel() <= Logger::WARN)
    Logger(__FILE__, __LINE__, Logger::WARN, __func__).stream()
#define LOG_ERROR if(Logger::LogLevel() <= Logger::ERROR)
    Logger(__FILE__, __LINE__, Logger::ERROR, __func__).stream()
#define LOG_FATAL if(Logger::LogLevel() <= Logger::FATAL)
    Logger(__FILE__, __LINE__, Logger::FATAL, __func__).stream()

const char* strerror_tl(int savedErrno);

#define CHECK_NOTNULL(val) \
  ::muduo::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))

// A small helper for CHECK_NOTNULL().
template <typename T>
T* CheckNotNull(Logger::SourceFile file, int line, const char *names, T* ptr)
{
  if (ptr == NULL)
  {
   Logger(file, line, Logger::FATAL).stream() << names;
  }
  return ptr;
}